package com.cdtye.itps.cms.util;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日期工具类
 * @author gaozx
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    /**日期正则*/
    public static final String DATE_REG = "[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}";
    /**日期时间正则*/
    public static final String DATETIME_REG = "[0-9]{4}/[0-9]{1,2}/[0-9]{1,2} [0-2]?[0-9]?:[0-5]?[0-9]?";
    /**日期格式*/
    private static Pattern datePattern = Pattern.compile(DATE_REG);
    /**日期时间格式*/
    private static Pattern dateTimePattern = Pattern.compile(DATETIME_REG);

    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYYMMDD = "yyyyMMdd";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    /**
     * 校验字符串是否默认的时间格式
     * @param date 日期字符串
     */
    public static boolean checkDate(String date){
        Matcher m = datePattern.matcher(date);
        return m.matches();
    }


    /**
     * 校验字符串是否默认的时间格式
     * @param date 日期字符串
     */
    public static boolean checkDateTime(String date){
        Matcher m = dateTimePattern.matcher(date);
        return m.matches();
    }

    /**
     * 校验字符串是否默认的时间格式
     * @param dateStr 日期字符串 yyyy/MM/dd
     * @return Date
     */
    public static Date parse(String dateStr) throws ParseException{
        return parse(dateStr,"yyyy/MM/dd");
    }

    /**
     * 校验字符串是否默认的时间格式
     * @param dateStr 日期字符串
     * @param pattern 日期格式
     * @return Date
     */
    public static Date parse(String dateStr,String pattern) throws ParseException{
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.parse(dateStr);
    }
    /**
     *
     * @description: 获得当天最小时间
     * @author: Jeff
     * @date: 2019年12月21日
     * @param date
     * @return
     */
    public static Date getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()),
                ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     *
     * @description: string转Date
     * @author: Jeff
     * @date: 2019年12月21日
     * @param time
     * @return
     */
    public static Date StringToDate(String time){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date dateTime = null;
        try {
            dateTime = simpleDateFormat.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dateTime;
    }

    /**
     *
     * @description: 获得当天最大时间
     * @author: Jeff
     * @date: 2019年12月21日
     * @param date
     * @return
     */
    public static Date getEndOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()),
                ZoneId.systemDefault());
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }
    public static List<String> getYearAllMonth(String year){
        List list=new ArrayList();
        for(int i=0;i<12;i++){
            if(i<9){
                list.add(year+"-0"+(i+1));
            }else{
                list.add(year+"-"+(i+1));
            }

        }
        return list;
    }



    public static String getCurrentYear(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        String year = String.valueOf(calendar.get(Calendar.YEAR));
        return year;
    }

    public static final String parseDateToStr(final String format, final Date date) {
        if(date == null){
            return "";
        }
        return new SimpleDateFormat(format).format(date);
    }

    public static Date longToDate(long lo){
        Date date = new Date(lo);
        //SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //return sd.format(date);
        return date;
    }

    public static String DateToString(Date time, String format){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        String dateTime = null;
        try {
            dateTime = simpleDateFormat.format(time);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dateTime;
    }

    public static Date StringToDate(String time, String format){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date dateTime = null;
        try {
            dateTime = simpleDateFormat.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dateTime;
    }

    //====================================当前时间加减======================

    /**
     * 时间加减小时
     *
     * @param startDate 要处理的时间，Null则为当前时间
     * @param hours     加减的小时
     * @return Date
     */
    public static Date dateAddHours(Date startDate, int hours) {
        if (startDate == null) {
            startDate = new Date();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        c.set(Calendar.HOUR, c.get(Calendar.HOUR) + hours);
        return c.getTime();
    }

    /**
     * 时间加减分钟
     *
     * @param startDate 要处理的时间，Null则为当前时间
     * @param minutes   加减的分钟
     * @return Date
     */
    public static Date dateAddMinutes(Date startDate, int minutes) {
        if (startDate == null) {
            startDate = new Date();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + minutes);
        return c.getTime();
    }

    /**
     * 时间加减秒数
     *
     * @param startDate 要处理的时间，Null则为当前时间
     * @param seconds   加减的秒数
     * @return Date
     */
    public static Date dateAddSeconds(Date startDate, int seconds) {
        if (startDate == null) {
            startDate = new Date();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        c.set(Calendar.SECOND, c.get(Calendar.SECOND) + seconds);
        return c.getTime();
    }

    /**
     * 时间加减年数
     *
     * @param startDate 要处理的时间，Null则为当前时间
     * @param years     加减的年数
     * @return Date
     */
    public static Date dateAddYears(Date startDate, int years) {
        if (startDate == null) {
            startDate = new Date();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        c.set(Calendar.YEAR, c.get(Calendar.YEAR) + years);
        return c.getTime();
    }

    /**
     * 时间加减月数
     *
     * @param startDate 要处理的时间，Null则为当前时间
     * @param months    加减的月数
     * @return Date
     */
    public static Date dateAddMonths(Date startDate, int months) {
        if (startDate == null) {
            startDate = new Date();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        c.set(Calendar.MONTH, c.get(Calendar.MONTH) + months);
        return c.getTime();
    }

    /**
     * 时间加减天数
     *
     * @param startDate 要处理的时间，Null则为当前时间
     * @param days      加减的天数
     * @return Date
     */
    public static Date dateAddDays(Date startDate, int days) {
        if (startDate == null) {
            startDate = new Date();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        c.set(Calendar.DATE, c.get(Calendar.DATE) + days);
        return c.getTime();
    }

    /**
     * 时间加减小时
     *
     * @param localDateTime 要处理的时间，Null则为当前时间
     * @param hours         加减的小时
     * @return Date
     */
    public static LocalDateTime localDateAddHours(LocalDateTime localDateTime, int hours) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }
        return localDateTime.plusHours(hours);
    }

    /**
     * 时间加减分钟
     *
     * @param localDateTime 要处理的时间，Null则为当前时间
     * @param minutes       加减的分钟
     * @return Date
     */
    public static LocalDateTime localDateAddMinutes(LocalDateTime localDateTime, int minutes) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }
        return localDateTime.plusMinutes(minutes);
    }

    /**
     * 时间加减秒数
     *
     * @param localDateTime 要处理的时间，Null则为当前时间
     * @param seconds       加减的秒数
     * @return Date
     */
    public static LocalDateTime localDateAddSeconds(LocalDateTime localDateTime, int seconds) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }
        return localDateTime.plusSeconds(seconds);
    }

    /**
     * 时间加减年数
     *
     * @param localDateTime 要处理的时间，Null则为当前时间
     * @param years         加减的年数
     * @return Date
     */
    public static LocalDateTime localDateAddYears(LocalDateTime localDateTime, int years) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }
        return localDateTime.plusYears(years);
    }

    /**
     * 时间加减月数
     *
     * @param localDateTime 要处理的时间，Null则为当前时间
     * @param months        加减的月数
     * @return Date
     */
    public static LocalDateTime localDateMonths(LocalDateTime localDateTime, int months) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }
        return localDateTime.plusMonths(months);
    }

    /**
     * 时间加减天数
     *
     * @param localDateTime 要处理的时间，Null则为当前时间
     * @param days          加减的天数
     * @return Date
     */
    public static LocalDateTime localDateAddDays(LocalDateTime localDateTime, int days) {
        if (localDateTime == null) {
            localDateTime = LocalDateTime.now();
        }
        return localDateTime.plusDays(days);
    }

    //====================================时间比较======================

    /**
     * 时间比较（如果myDate>compareDate返回1，<返回-1，相等返回0）
     *
     * @param myDate      时间
     * @param compareDate 要比较的时间
     * @return int
     */
    public static int dateCompare(Date myDate, Date compareDate) {
        Calendar myCal = Calendar.getInstance();
        Calendar compareCal = Calendar.getInstance();
        myCal.setTime(myDate);
        compareCal.setTime(compareDate);
        return myCal.compareTo(compareCal);
    }

    /**
     * 获取两个时间中最小的一个时间
     *
     * @param date
     * @param compareDate
     * @return Date
     */
    public static Date dateMin(Date date, Date compareDate) {
        if (date == null) {
            return compareDate;
        }
        if (compareDate == null) {
            return date;
        }
        if (1 == dateCompare(date, compareDate)) {
            return compareDate;
        } else if (-1 == dateCompare(date, compareDate)) {
            return date;
        }
        return date;
    }

    /**
     * 获取两个时间中最大的一个时间
     *
     * @param date
     * @param compareDate
     * @return Date
     */
    public static Date dateMax(Date date, Date compareDate) {
        if (date == null) {
            return compareDate;
        }
        if (compareDate == null) {
            return date;
        }
        if (1 == dateCompare(date, compareDate)) {
            return date;
        } else if (-1 == dateCompare(date, compareDate)) {
            return compareDate;
        }
        return date;
    }

    /**
     * 获取时间当年某个月的最后一天
     *
     * @param startDate
     * @param month     月份
     * @return int 天数
     */
    public static int getLastDayOfMonth(Date startDate, int month) {
        if (startDate == null) {
            startDate = new Date();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        c.set(c.get(Calendar.YEAR), month, 1);
        c.add(Calendar.DATE, -1);
        int day = c.get(Calendar.DAY_OF_MONTH);
        return day;
    }

    /**
     * 获取固定日期范围内的所有日期，以数组形式返回
     */
    public static List<Date> getAllDays(Date startTime, Date endTime) {
        List<Date> listDay = new ArrayList<>();
        Date dtDay = new Date();
        for (dtDay = startTime; dtDay.compareTo(endTime) <= 0; dtDay = dateAddDays(dtDay, 1)) {
            listDay.add(dtDay);
        }
        return listDay;
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    public static List<String> getYearMonth(String begin,String end) throws Exception{
        List<String> list=new ArrayList<>();
        if(begin.equals(end)){
            list.add(begin);
            return list;
        }
        list.add(begin);
        while (true){
            Date beginDate=DateUtils.parse(begin,"yyyy-MM");
            Date date= org.apache.commons.lang3.time.DateUtils.addMonths(beginDate,1);
            String dateStr= parseDateToStr("yyyy-MM",date);
            begin=dateStr;
            list.add(dateStr);
            if(end.equals(dateStr)){
                break;
            }
        }
        return list;
    }

    /**
     * 日期加减
     * @param date
     * @param num
     * @return
     */
    public static Date addDay(Date date, int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, num);
        return calendar.getTime();
    }
}
